/* Copyright Statement:
 *
 * This software/firmware and related documentation ("AutoChips Software") are
 * protected under relevant copyright laws. The information contained herein is
 * confidential and proprietary to AutoChips Inc. and/or its licensors. Without
 * the prior written permission of AutoChips inc. and/or its licensors, any
 * reproduction, modification, use or disclosure of AutoChips Software, and
 * information contained herein, in whole or in part, shall be strictly
 * prohibited.
 *
 * AutoChips Inc. (C) 2023. All rights reserved.
 *
 * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
 * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("AUTOCHIPS SOFTWARE")
 * RECEIVED FROM AUTOCHIPS AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
 * ON AN "AS-IS" BASIS ONLY. AUTOCHIPS EXPRESSLY DISCLAIMS ANY AND ALL
 * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
 * NONINFRINGEMENT. NEITHER DOES AUTOCHIPS PROVIDE ANY WARRANTY WHATSOEVER WITH
 * RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
 * INCORPORATED IN, OR SUPPLIED WITH THE AUTOCHIPS SOFTWARE, AND RECEIVER AGREES
 * TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
 * RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
 * OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN AUTOCHIPS
 * SOFTWARE. AUTOCHIPS SHALL ALSO NOT BE RESPONSIBLE FOR ANY AUTOCHIPS SOFTWARE
 * RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
 * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND AUTOCHIPS'S
 * ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE AUTOCHIPS SOFTWARE
 * RELEASED HEREUNDER WILL BE, AT AUTOCHIPS'S OPTION, TO REVISE OR REPLACE THE
 * AUTOCHIPS SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
 * CHARGE PAID BY RECEIVER TO AUTOCHIPS FOR SUCH AUTOCHIPS SOFTWARE AT ISSUE.
 */

/*!
 * @file ac780x_adc.h
 *
 * @brief This file provides analog to digital converter module integration functions interfaces.
 *
 */

#ifndef _AC780X_ADC_H
#define _AC780X_ADC_H

#ifdef __cplusplus
extern "C" {
#endif

/* ===========================================  Includes  =========================================== */
#include "ac7803x.h"

/* ============================================  Define  ============================================ */
/*!
 * @brief ADC instance index macro.
 */
#define ADC_INDEX(ADCx)    ((uint8_t)(((uint32_t)(ADCx) - ADC0_BASE)))

/*!
 * @brief ADC regular group sequence length.
 */
#define ADC_REGULAR_SEQUENCE_LEGNTH         (21U)

/*!
 * @brief ADC injected group sequence length.
 */
#define ADC_INJECT_SEQUENCE_LEGNTH          (4U)

/* ===========================================  Typedef  ============================================ */
/*!
 * @brief ADC channel type enumeration.
 */
typedef enum
{
    ADC_CH_0 = 0U,   /*!< ADC channel 0 */
    ADC_CH_1,        /*!< ADC channel 1 */
    ADC_CH_2,        /*!< ADC channel 2 */
    ADC_CH_3,        /*!< ADC channel 3 */
    ADC_CH_4,        /*!< ADC channel 4 */
    ADC_CH_5,        /*!< ADC channel 5 */
    ADC_CH_6,        /*!< ADC channel 6 */
    ADC_CH_7,        /*!< ADC channel 7 */
    ADC_CH_8,        /*!< ADC channel 8 */
    ADC_CH_9,        /*!< ADC channel 9 */
    ADC_CH_10,       /*!< ADC channel 10 */
    ADC_CH_11,       /*!< ADC channel 11 */
    ADC_CH_12,       /*!< ADC channel 12 */
    ADC_CH_13,       /*!< ADC channel 13 */
    ADC_CH_14,       /*!< ADC channel 14 */
    ADC_CH_15,       /*!< ADC channel 15 */
    ADC_CH_16,       /*!< ADC channel 16 */
    ADC_CH_17,       /*!< ADC channel 17 */
    ADC_CH_18,       /*!< ADC channel 18 */
    ADC_CH_VIN,      /*!< ADC channel T-Sensor and Bandgap channel */
    ADC_CH_CALI,     /*!< ADC channel  Internal calibration channel */
    ADC_CH_MAX,      /*!< Invalid channel */
} ADC_ChannelType;

/*!
 * @brief ADC sample time enumeration.
 */
typedef enum
{
    ADC_SPT_CLK_8 = 0U,          /*!< ADC Sample time 8 Clock Cycle */
    ADC_SPT_CLK_10,              /*!< ADC Sample time 10 Clock Cycle */
    ADC_SPT_CLK_15,              /*!< ADC Sample time 15 Clock Cycle */
    ADC_SPT_CLK_33,              /*!< ADC Sample time 33 Clock Cycle */
    ADC_SPT_CLK_64,              /*!< ADC Sample time 64 Clock Cycle */
    ADC_SPT_CLK_140,             /*!< ADC Sample time 140 Clock Cycle */
    ADC_SPT_CLK_215,             /*!< ADC Sample time 215 Clock Cycle */
    ADC_SPT_CLK_6,               /*!< ADC Sample time 6 Clock Cycle */
    ADC_SPT_CLK_MAX,             /*!< Invalid ADC Sample time */
} ADC_SampleTimeType;

/*!
 * @brief ADC clock prescaler enumeration.
 */
typedef enum
{
    ADC_CLK_PRESCALER_1 = 0U,    /*!< Clock presalcer divide 1 */
    ADC_CLK_PRESCALER_2,         /*!< Clock presalcer divide 2 */
    ADC_CLK_PRESCALER_3,         /*!< Clock presalcer divide 3 */
    ADC_CLK_PRESCALER_4,         /*!< Clock presalcer divide 4 */
    ADC_CLK_PRESCALER_5,         /*!< Clock presalcer divide 5 */
    ADC_CLK_PRESCALER_6,         /*!< Clock presalcer divide 6 */
    ADC_CLK_PRESCALER_7,         /*!< Clock presalcer divide 7 */
    ADC_CLK_PRESCALER_8,         /*!< Clock presalcer divide 8 */
    ADC_CLK_PRESCALER_9,         /*!< Clock presalcer divide 9 */
    ADC_CLK_PRESCALER_10,        /*!< Clock presalcer divide 10 */
    ADC_CLK_PRESCALER_11,        /*!< Clock presalcer divide 11 */
    ADC_CLK_PRESCALER_12,        /*!< Clock presalcer divide 12 */
    ADC_CLK_PRESCALER_13,        /*!< Clock presalcer divide 13 */
    ADC_CLK_PRESCALER_14,        /*!< Clock presalcer divide 14 */
    ADC_CLK_PRESCALER_15,        /*!< Clock presalcer divide 15 */
    ADC_CLK_PRESCALER_16,        /*!< Clock presalcer divide 16 */
    ADC_CLK_PRESCALER_MAX,       /*!< Invalid Clock presalcer */
} ADC_ClkPrescalerType;

/*!
 * @brief ADC data alignment enumeration.
 */
typedef enum
{
    ADC_DATA_ALIGN_RIGHT = 0U,   /*!< Data right alignment */
    ADC_DATA_ALIGN_LEFT,         /*!< Data left alignment */
} ADC_DataAlignType;

/*!
 * @brief ADC analog monitor trigger mode enumeration.
 */
typedef enum
{
    ADC_AMO_TRIGGER_LEVEL = 0U,  /*!< AMO Level trigger */
    ADC_AMO_TRIGGER_EDGE,        /*!< AMO Edge trigger */
} ADC_AMOTriggerModeType;

/*!
 * @brief ADC trigger convert mode enumeration.
 */
typedef enum
{
    ADC_TRIGGER_INTERNAL = 0U,   /*!< Internal software trigger */
    ADC_TRIGGER_EXTERNAL,        /*!< External signal trigger */
} ADC_TriggerConvertType;

/*!
 * @brief ADC power mode enumeration.
 */
typedef enum
{
    ADC_POWER_DOWN = 0U,         /*!< Power down mode */
    ADC_POWER_ON,                /*!< Power on mode */
} ADC_PowerModeType;

/*!
 * @brief ADC lowpower mode conversion interval.
 */
typedef enum
{
    ADC_CONVERSION_INTERVAL_1MS = 0U, /*!< ADC lowpower mode conversion interval 1mS */
    ADC_CONVERSION_INTERVAL_2MS,      /*!< ADC lowpower mode conversion interval 2mS */
    ADC_CONVERSION_INTERVAL_3MS,      /*!< ADC lowpower mode conversion interval 3mS */
    ADC_CONVERSION_INTERVAL_4MS,      /*!< ADC lowpower mode conversion interval 4mS */
    ADC_CONVERSION_INTERVAL_5MS,      /*!< ADC lowpower mode conversion interval 5mS */
    ADC_CONVERSION_INTERVAL_6MS,      /*!< ADC lowpower mode conversion interval 6mS */
    ADC_CONVERSION_INTERVAL_7MS,      /*!< ADC lowpower mode conversion interval 7mS */
    ADC_CONVERSION_INTERVAL_8MS,      /*!< ADC lowpower mode conversion interval 8mS */
    ADC_CONVERSION_INTERVAL_9MS,      /*!< ADC lowpower mode conversion interval 9mS */
    ADC_CONVERSION_INTERVAL_10MS,     /*!< ADC lowpower mode conversion interval 10mS */
} ADC_ConversionIntervalType;

/*!
 * @brief ADC reference voltage source selection.
 */
typedef enum
{
    ADC_VOLTAGEREF_VDDA = 0U,      /*!< ADC select VDDA as reference voltage */
    ADC_VOLTAGEREF_AGPIO,          /*!< ADC select PA1 and PA0 as reference voltage */
    ADC_VOLTAGEREF_VREF,           /*!< ADC select VREF PAD as reference voltage */
} ADC_VrefType;

/*!
 * @brief ADC internal calibration signal selection.
 */
typedef enum
{
    ADC_CALI_SIGNAL_FLOATING = 0U, /*!< ADC calibration signal select floating */
    ADC_CALI_SIGNAL_VREF1_8,       /*!< ADC calibration signal select 1/8 of the reference voltage */
    ADC_CALI_SIGNAL_VREF2_8,       /*!< ADC calibration signal select 2/8 of the reference voltage */
    ADC_CALI_SIGNAL_VREF3_8,       /*!< ADC calibration signal select 3/8 of the reference voltage */
    ADC_CALI_SIGNAL_VREF4_8,       /*!< ADC calibration signal select 4/8 of the reference voltage */
    ADC_CALI_SIGNAL_VREF5_8,       /*!< ADC calibration signal select 5/8 of the reference voltage */
    ADC_CALI_SIGNAL_VREF6_8,       /*!< ADC calibration signal select 6/8 of the reference voltage */
    ADC_CALI_SIGNAL_VREF7_8,       /*!< ADC calibration signal select 7/8 of the reference voltage */
} ADC_GEOEType;

/*!
 * @brief ADC internal voltage channel selection.
 */
typedef enum
{
    ADC_INTERNAL_BG = 0U,          /*!< Bandgap singal */
    ADC_INTERNAL_TSENSOR,          /*!< T-sensor singal */
} ADC_VINType;

/*!
 * @brief ADC configuration structure.
 */
typedef struct
{
    /* General parameters */
    ADC_ClkPrescalerType clkPsc;                 /*!< Clock prescaler ratio */
    ACTION_Type scanModeEn;                      /*!< Enable/disable scan mode for regular and injected group */
    ACTION_Type continuousModeEn;                /*!< Enable/disable continuous mode */
    ACTION_Type regularDiscontinuousModeEn;      /*!< Enable/disable discontinuous mode for regular group */
    ACTION_Type injectDiscontinuousModeEn;       /*!< Enable/disable discontinuous mode for injected group */
    ACTION_Type injectAutoModeEn;                /*!< Enable/disable interval mode for mode3/5 */
    ACTION_Type intervalModeEn;                  /*!< Enable/disable antomatic mode for injected group */
    uint8_t regularDiscontinuousNum;             /*!< Regular discontinuous mode number */
    ACTION_Type EOCInterruptEn;                  /*!< Enable/disable EOC interrupt */
    ACTION_Type IEOCInterruptEn;                 /*!< Enable/disable IEOC interrupt */
    ACTION_Type interruptEn;                     /*!< Enable/disable adc interrupt  */
    ACTION_Type regularDMAEn;                    /*!< Enable/disable regular dma mode */
    ADC_TriggerConvertType regularTriggerMode;   /*!< Select internal or external trigger for regular group */
    ADC_TriggerConvertType injectTriggerMode;    /*!< Select internal or external trigger for injected group */
    uint8_t regularSequenceLength;               /*!< Regular sequence length */
    uint8_t injectSequenceLength;                /*!< Injected sequence length */
    ADC_DataAlignType dataAlign;                 /*!< 0:Right alignment; 1:left alignment */
    ADC_VrefType voltageRef;                     /*!< 0:VDDA; 1:PA1/PA0(AGPIO); 2:VREF+/VREF-(PAD) */
    DeviceCallback_Type callBack;                /*!< Callback pointer */
    ADC_PowerModeType powerMode;                 /*!< Power mode */
} ADC_ConfigType;

/*!
 * @brief ADC analog monitor configuration structure.
 */
typedef struct
{
    ADC_AMOTriggerModeType AMOTriggerMode;      /*!< 0:level trigger; 1:edge trigger */
    ACTION_Type AMOInterruptEn;                 /*!< Enable/disable AMO interrupt */
    ACTION_Type AMORegularEn;                   /*!< Enable/disable analog monitor regular group mode */
    ACTION_Type AMOInjectEn;                    /*!< Enable/disable analog monitor injected group mode */
    ACTION_Type AMOSingleModeEn;                /*!< Enable/disable analog monitor single channel mode */
    ADC_ChannelType AMOSingleChannel;           /*!< Select analog monitor single channel */
    uint16_t AMOHighThreshold;                  /*!< Set analog monitor high Threshold */
    uint16_t AMOLowThreshold;                   /*!< Set analog monitor low Threshold */
    uint16_t AMOHighOffset;                     /*!< Set analog monitor high Offset */
    uint16_t AMOLowOffset;                      /*!< Set analog monitor low Offset */
} ADC_AMOConfigType;

/* ==========================================  Variables  =========================================== */

/* ====================================  Functions declaration  ===================================== */
/*!
 * @brief ADC initialize.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @param[in] config: pointer to configuration structure
 * @return none
 */
void ADC_Init(ADC_Type *ADCx, const ADC_ConfigType *config);

/*!
 * @brief ADC De-initialize.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @return none
 */
void ADC_DeInit(ADC_Type *ADCx);

/*!
 * @brief Get ADC configuration.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @param[out] config: pointer to ADC configuration structure
 */
void ADC_GetConfig(ADC_Type *ADCx,  ADC_ConfigType * const config);

/*!
 * @brief Set adc regular group channel and sample time.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @param[in] channel: adc channel
 *               - ADC_CH_0
 *               - ADC_CH_1
 *               - ...
 *               - ADC_CH_18
 *               - ADC_CH_VIN
 *               - ADC_CH_CALI
 * @param[in] spt: sample time
 *               - ADC_SPT_CLK_8
 *               - ADC_SPT_CLK_10
 *               - ADC_SPT_CLK_15
 *               - ADC_SPT_CLK_33
 *               - ADC_SPT_CLK_64
 *               - ADC_SPT_CLK_140
 *               - ADC_SPT_CLK_215
 *               - ADC_SPT_CLK_6
 * @param[in] seq: regular group convert sequence
 *               - 0 ~ 20
 * @return none
 */
void ADC_SetRegularGroupChannel(ADC_Type *ADCx, ADC_ChannelType channel, ADC_SampleTimeType spt, uint8_t seq);

/*!
 * @brief Get adc regular group channel and sample time.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @param[in] seq: regular group convert sequence
 *               - 0 ~ 20
 * @param[out] channel: adc channel
 *               - ADC_CH_0
 *               - ADC_CH_1
 *               - ...
 *               - ADC_CH_18
 *               - ADC_CH_VIN
 *               - ADC_CH_CALI
 * @param[out] spt: sample time
 *               - ADC_SPT_CLK_8
 *               - ADC_SPT_CLK_10
 *               - ADC_SPT_CLK_15
 *               - ADC_SPT_CLK_33
 *               - ADC_SPT_CLK_64
 *               - ADC_SPT_CLK_140
 *               - ADC_SPT_CLK_215
 *               - ADC_SPT_CLK_6
 * @return none
 */
void ADC_GetRegularGroupChannel(ADC_Type *ADCx, ADC_ChannelType *channel, ADC_SampleTimeType *spt, uint8_t seq);

/*!
 * @brief Set adc injected group channel and sample time.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @param[in] channel: adc channel
 *               - ADC_CH_0
 *               - ADC_CH_1
 *               - ...
 *               - ADC_CH_18
 *               - ADC_CH_VIN
 *               - ADC_CH_CALI
 * @param[in] spt: sample time
 *               - ADC_SPT_CLK_8
 *               - ADC_SPT_CLK_10
 *               - ADC_SPT_CLK_15
 *               - ADC_SPT_CLK_33
 *               - ADC_SPT_CLK_64
 *               - ADC_SPT_CLK_140
 *               - ADC_SPT_CLK_215
 *               - ADC_SPT_CLK_6
 * @param[in] seq: injected group convert sequence
 *               - 0 ~ 3
 * @return none
 */
void ADC_SetInjectGroupChannel(ADC_Type *ADCx, ADC_ChannelType channel, ADC_SampleTimeType spt, uint8_t seq);

/*!
 * @brief Get adc injected group channel and sample time.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @param[in] seq: injected group convert sequence
 *               - 0 ~ 3
 * @param[out] channel: adc channel
 *               - ADC_CH_0
 *               - ADC_CH_1
 *               - ...
 *               - ADC_CH_18
 *               - ADC_CH_VIN
 *               - ADC_CH_CALI
 * @param[out] spt: sample time
 *               - ADC_SPT_CLK_8
 *               - ADC_SPT_CLK_10
 *               - ADC_SPT_CLK_15
 *               - ADC_SPT_CLK_33
 *               - ADC_SPT_CLK_64
 *               - ADC_SPT_CLK_140
 *               - ADC_SPT_CLK_215
 *               - ADC_SPT_CLK_6
 * @return none
 */
void ADC_GetInjectGroupChannel(ADC_Type *ADCx, ADC_ChannelType *channel, ADC_SampleTimeType *spt, uint8_t seq);

/*!
 * @brief Set adc analog monitor.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @param[in] config: pointer to configuration structure
 * @return none
 */
void ADC_SetAnalogMonitor(ADC_Type *ADCx, ADC_AMOConfigType *config);

/*!
 * @brief Get adc analog monitor configuration.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @param[out] config: pointer to configuration structure
 * @return none
 */
void ADC_GetAnalogMonitor(ADC_Type *ADCx, ADC_AMOConfigType *config);

/*!
 * @brief Auto calibration function for ADC.  This function should be called every time after
 * ADC reset or power on.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @return none
 */
void ADC_DRV_AutoCalibration(ADC_Type *ADCx);

/*!
 * @brief Set adc receive dma.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @param[in] DMAx:DMA Channel type pointer,
 *                 -DMA0_CHANNEL0
 *                 -DMA0_CHANNEL1
 *                 -DMA0_CHANNEL2
 *                 -DMA0_CHANNEL3
 * @param[in] rxBuffer: point to receive buffer
 * @param[in] transferNum: Transfer data numbers, 0~32767, bit15 should be 0
 * @param[in] callback: point to DMA callback function
 * @return none
 */
void ADC_SetReceiveDMA(ADC_Type *ADCx, DMA_ChannelType *DMAx, uint16_t *rxBuffer,
                       uint16_t transferNum, DeviceCallback_Type callback);

/*!
 * @brief Set adc callback function.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @param[in] func: callback function
 * @return none
 */
void ADC_SetCallback(ADC_Type *ADCx, const DeviceCallback_Type func);

#ifdef __cplusplus
}
#endif

#endif /* _AC780X_ADC_H */

/* =============================================  EOF  ============================================== */
